encyklopedia.space

Styles (XAML)

Style w języku XAML (eXtensible Application Markup Language) jest deklaratywnym opisem wyglądu oraz zachowania elementów interfejsu użytkownika. Pozwala na grupowanie zestawu właściwości, zdarzeń i szablonów (np. ControlTemplate, DataTemplate) pod jedną nazwą, którą można później zastosować do dowolnej liczby kontrolki. Dzięki temu stylowanie aplikacji staje się bardziej spójne, łatwe w utrzymaniu oraz umożliwia ponowne użycie kodu.

Historia

Pierwsze wsparcie dla stylów w XAML pojawiło się w 2006 roku wraz z wprowadzeniem platformy Windows Presentation Foundation (WPF). Następnie mechanizm stylów został zaadaptowany w Silverlight (2007), a później w Universal Windows Platform (UWP) oraz w Xamarin.Forms.

Podstawowa składnia

Style definiuje się zwykle w elemencie <ResourceDictionary> znajdującym się w sekcji <Window.Resources>, <Page.Resources> lub w osobnym pliku .xaml. Najważniejsze atrybuty to:

  • TargetType – określa typ kontrolki, do której styl ma być zastosowany.
  • x:Key – unikalny identyfikator stylu. Brak klucza powoduje, że styl staje się domyślnym stylem dla określonego TargetType.
  • BasedOn – umożliwia dziedziczenie właściwości z innego stylu.

Przykład podstawowego stylu

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <Style x:Key="PrimaryButtonStyle"
               TargetType="{x:Type Button}">
            <Setter Property="Background" Value="#FF007ACC"/>
            <Setter Property="Foreground" Value="White"/>
            <Setter Property="FontWeight" Value="Bold"/>
            <Setter Property="Padding" Value="10,5"/>
            <Setter Property="BorderThickness" Value="0"/>
        </Style>
    </Window.Resources>

    <Grid>
        <Button Style="{StaticResource PrimaryButtonStyle}"
                Content="Kliknij mnie" HorizontalAlignment="Center"
                VerticalAlignment="Center"/>
    </Grid>
</Window>

W powyższym przykładzie styl PrimaryButtonStyle definiuje zestaw właściwości wizualnych dla wszystkich przycisków Button, które odwołują się do tego zasobu.

Style bazowane (BasedOn)

Wielokrotne definiowanie podobnych stylów może prowadzić do duplikacji kodu. Funkcja BasedOn pozwala na stworzenie stylu bazowego, a następnie rozszerzenie go o dodatkowe ustawienia:

<Style x:Key="BaseButtonStyle"
       TargetType="{x:Type Button}">
    <Setter Property="Background" Value="#FF007ACC"/>
    <Setter Property="Foreground" Value="White"/>
</Style>

<Style x:Key="AccentButtonStyle"
       TargetType="{x:Type Button}"
       BasedOn="{StaticResource BaseButtonStyle}">
    <Setter Property="BorderBrush" Value="Gold"/>
    <Setter Property="BorderThickness" Value="2"/>
</Style>

DynamicResource vs StaticResource

Do odwoływania się do stylu używa się dwóch rodzajów odwołań:

  • StaticResource – wartość jest rozwiązywana raz, podczas ładowania XAML. Zapewnia lepszą wydajność.
  • DynamicResource – odwołuje się w czasie wykonywania, umożliwiając zmianę stylu w locie (np. przy zmianie tematu aplikacji).

Użycie stylów w MVVM

Model MVVM (Model-View-ViewModel) zaleca utrzymanie logiki interfejsu w warstwie XAML. Style są idealnym narzędziem do oddzielenia wyglądu od logiki, ponieważ pozwalają na centralne definiowanie wyglądu, które może być modyfikowane bez ingerencji w kod C#.

Style w UWP i Xamarin.Forms

Choć składnia XAML w UWP i Xamarin.Forms różni się nieco od tej w WPF, koncepcja stylu pozostaje taka sama. W UWP dostępne są dodatkowe właściwości, takie jak ThemeResource, które umożliwiają automatyczną adaptację do trybu jasnego lub ciemnego. W Xamarin.Forms styl definiuje się w ResourceDictionary aplikacji i może być stosowany do wszystkich platform (Android, iOS, Windows).

Najlepsze praktyki

  1. Używaj nazw opisowych dla stylów, np. PrimaryButtonStyle, ErrorTextBlockStyle.
  2. Wykorzystuj BasedOn aby unikać duplikacji.
  3. Utrzymuj style w oddzielnych plikach XAML (np. Styles.xaml) i importuj je w App.xaml jako ResourceDictionary.MergedDictionaries.
  4. W miarę możliwości używaj DynamicResource w sytuacjach, gdy styl może się zmienić w czasie działania aplikacji.
  5. Stosuj ThemeResource (w UWP) do obsługi motywów systemowych.

Przykład organizacji zasobów

<Application x:Class="MyApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Styles/Buttons.xaml"/>
                <ResourceDictionary Source="/Styles/TextBlocks.xaml"/>
                <ResourceDictionary Source="/Styles/Containers.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

Zobacz także